<html>
<head></head>
<body><a name="ZH-CN_TOPIC_0000002278863244"></a><a name="ZH-CN_TOPIC_0000002278863244"></a>
<h1>基础自定义弹出框 (CustomDialog)(不推荐)</h1>
<div><p>CustomDialog是自定义弹出框，可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹出框。具体用法请参考<a
        href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box"
        target="_blank">自定义弹出框</a>。</p>
    <div class="note"><img originheight="38" originwidth="102"
                           src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163041.78406772364688925865366986675575:50001231000000:2800:4368310263E1549E2920237419D8CA58ED640022FF7B4CA85B59FB230B0B9DCF.png"><span
            class="notetitle"> </span>
        <div class="notebody"><p>当前，ArkUI弹出框默认为非页面级弹出框，在页面路由跳转时，如果开发者未调用close方法将其关闭，弹出框将不会自动关闭。若需实现在跳转页面时覆盖弹出框的场景，可以使用<a
                href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-navigation-navigation#页面显示类型">组件导航子页面显示类型的弹窗类型</a>或者<a
                href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-embedded-dialog">页面级弹出框</a>。
        </p></div>
    </div>
    <p>默认为模态弹窗且有蒙层，不可与蒙层下方控件进行交互（不支持点击和手势等向下透传）。可以通过配置<a
            href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box#customdialogcontrolleroptions对象说明"
            target="_blank">isModal</a>来实现模态和非模态弹窗，详细说明可参考<a
            href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-dialog-overview#弹窗的种类">弹窗的种类</a>。
    </p>
    <p>
        当isModal为true时，弹出框为模态弹窗，且弹窗周围的蒙层区不支持透传。isModal为false时，弹出框为非模态弹窗，且弹窗周围的蒙层区可以透传。因此如果需要同时允许弹出框的交互和弹出框外页面的交互行为，需要将弹出框设置为非模态。</p>
    <div class="section" id="生命周期"><a name="ZH-CN_TOPIC_0000002278863244__%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"></a><a
            name="%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"></a>     <h4>生命周期</h4>
        <p>从API version 19开始，自定义弹出框提供了生命周期函数用于通知用户该弹出框的生命周期。生命周期的触发时序依次为：onWillAppear
            -&gt; onDidAppear -&gt; onWillDisappear -&gt; onDidDisappear。</p>
        <div class="tablenoborder">
            <table>
                <thead>
                <tr>
                    <th align="left" class="cellrowborder" id="mcps1.3.5.3.1.4.1.1" valign="top"
                        width="33.33333333333333%">名称
                    </th>
                    <th align="left" class="cellrowborder" id="mcps1.3.5.3.1.4.1.2" valign="top"
                        width="33.33333333333333%">类型
                    </th>
                    <th align="left" class="cellrowborder" id="mcps1.3.5.3.1.4.1.3" valign="top"
                        width="33.33333333333333%">说明
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">onWillAppear</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">Callback&lt;void&gt;</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">弹出框显示动效前的事件回调。</td>
                </tr>
                <tr>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">onDidAppear</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">Callback&lt;void&gt;</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">弹出框弹出后的事件回调。</td>
                </tr>
                <tr>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">onWillDisappear</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">Callback&lt;void&gt;</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">弹出框退出动效前的事件回调。</td>
                </tr>
                <tr>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">onDidDisappear</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">Callback&lt;void&gt;</td>
                    <td class="cellrowborder" valign="top" width="33.33333333333333%">弹出框消失后的事件回调。</td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
    <div class="section" id="创建自定义弹出框"><a
            name="ZH-CN_TOPIC_0000002278863244__%E5%88%9B%E5%BB%BA%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BC%B9%E5%87%BA%E6%A1%86"></a><a
            name="%E5%88%9B%E5%BB%BA%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BC%B9%E5%87%BA%E6%A1%86"></a>     <h4>
        创建自定义弹出框</h4>
        <ol>
            <li><p>
                使用@CustomDialog装饰器装饰自定义弹出框，可在此装饰器内自定义弹出框内容。CustomDialogController需在@Component内定义。</p>
                <pre class="ts">@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController

  build() {
    Column() {
      Text('我是内容')
        .fontSize(20)
    }.height(60).justifyContent(FlexAlign.Center)
  }
}</pre>
            </li>
            <li><p>创建构造器，与装饰器呼应相连。</p>
                <pre class="ts"> @Entry
 @Component
 struct CustomDialogUser {
   dialogController: CustomDialogController = new CustomDialogController({
     builder: CustomDialogExample(),
   })
 }</pre>
            </li>
            <li><p>点击与onClick事件绑定的组件使弹出框弹出。</p>
                <pre class="ts">@Entry
@Component
struct CustomDialogUser {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample(),
  })

  build() {
    Column() {
      Button('click me')
        .onClick(() =&gt; {
          this.dialogController.open();
        })
    }.width('100%').margin({ top: 5 })
  }
}</pre>
                <p><span><img originheight="712" originwidth="330"
                              src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163041.75918365355522712585856021695437:50001231000000:2800:AF2C087F5B50A3FF2FD300F419F4F1C5707ED15FF3161614090348F687E92D8F.png"></span>
                </p></li>
        </ol>
    </div>
    <div class="section" id="弹出框的交互"><a
            name="ZH-CN_TOPIC_0000002278863244__%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E4%BA%A4%E4%BA%92"></a><a
            name="%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E4%BA%A4%E4%BA%92"></a>     <h4>弹出框的交互</h4>
        <p>弹出框可用于数据交互，完成用户一系列响应操作。</p>
        <ol>
            <li><p>在@CustomDialog装饰器内添加按钮和数据函数。</p>
                <pre class="ts">@CustomDialog
struct CustomDialogExample {
  cancel: () =&gt; void = () =&gt; {
  }
  confirm: () =&gt; void = () =&gt; {
  }
  controller: CustomDialogController;

  build() {
    Column() {
      Text('我是内容').fontSize(20).margin({ top: 10, bottom: 10 })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('cancel')
          .onClick(() =&gt; {
            this.controller.close();
            if (this.cancel) {
              this.cancel();
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
        Button('confirm')
          .onClick(() =&gt; {
            this.controller.close();
            if (this.confirm) {
              this.confirm();
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })
    }
  }
}</pre>
            </li>
            <li><p>页面内需要在构造器内进行接收，同时创建相应的函数操作。</p>
                <pre class="ts">@Entry
@Component
struct CustomDialogUser {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: ()=&gt; { this.onCancel() },
      confirm: ()=&gt; { this.onAccept() },
    }),
  });

  onCancel() {
    console.info('Callback when the first button is clicked');
  }

  onAccept() {
    console.info('Callback when the second button is clicked');
  }

  build() {
    Column() {
      Button('click me')
        .onClick(() =&gt; {
          this.dialogController.open();
        })
    }.width('100%').margin({ top: 5 })
  }
}</pre>
                <p><span><img originheight="760" originwidth="345"
                              src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163041.07878275092305504308000755634445:50001231000000:2800:9B2CBBFD10607CAD5346ADF57F844998FB56A7C03E177E683FF88042A3167687.png"></span>
                </p>
                <p>3.可通过弹出框中的按钮实现路由跳转，同时获取跳转页面向当前页传入的参数。</p>
                <pre class="ts">// Index.ets
@CustomDialog
struct CustomDialogExample {
  @Link textValue: string;
  controller?: CustomDialogController;
  cancel: () =&gt; void = () =&gt; {
  }
  confirm: () =&gt; void = () =&gt; {
  }

  build() {
    Column({ space: 20 }) {
      if (this.textValue != '') {
        Text(`第二个页面的内容为：${this.textValue}`)
          .fontSize(20)
      } else {
        Text('是否获取第二个页面的内容')
          .fontSize(20)
      }
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('cancel')
          .onClick(() =&gt; {
            if (this.controller != undefined) {
              this.controller.close();
              this.cancel();
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
        Button('confirm')
          .onClick(() =&gt; {
            if (this.controller != undefined &amp;&amp; this.textValue != '') {
              this.controller.close();
            } else if (this.controller != undefined) {
              this.getUIContext().getRouter().pushUrl({
                url: 'pages/Index2'
              });
              this.controller.close();
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })
    }.borderRadius(10).padding({ top: 20 })
  }
}

@Entry
@Component
struct CustomDialogUser {
  @State textValue: string = '';
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: () =&gt; {
        this.onCancel()
      },
      confirm: () =&gt; {
        this.onAccept()
      },
      textValue: this.textValue
    })
  });

  // 在自定义组件即将析构销毁时将dialogController置空
  aboutToDisappear() {
    this.dialogController = null; // 将dialogController置空
  }

  onPageShow() {
    const params = this.getUIContext().getRouter().getParams() as Record&lt;string, string&gt;; // 获取传递过来的参数对象
    if (params) {
      this.dialogController?.open();
      this.textValue = params.info as string; // 获取info属性的值
    }
  }

  onCancel() {
    console.info('Callback when the first button is clicked');
  }

  onAccept() {
    console.info('Callback when the second button is clicked');
  }

  exitApp() {
    console.info('Click the callback in the blank area');
  }

  build() {
    Column() {
      Button('click me')
        .onClick(() =&gt; {
          if (this.dialogController != null) {
            this.dialogController.open();
          }
        }).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
  }
}</pre>
                <pre class="ts">// Index2.ets
@Entry
@Component
struct Index2 {
  @State message: string = '点击返回';

  build() {
    Column() {
      Button(this.message)
        .type(ButtonType.Capsule)
        .onClick(() =&gt; {
           this.getUIContext().getRouter().back({
             url: 'pages/Index',
             params: {
             info: 'Hello World'
           }
        });
      })
    }.width('100%').height('100%').margin({ top: 20 })
  }
}</pre>
                <p><span><img originheight="682" originwidth="352"
                              src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163042.35668957903630806699201454648478:50001231000000:2800:875AA4306BE14360DA3795F87C6827FCF6BF64F47E6CDA809778871015FBEF6C.gif"></span>
                </p></li>
        </ol>
    </div>
    <div class="section" id="弹出框的动画"><a
            name="ZH-CN_TOPIC_0000002278863244__%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E5%8A%A8%E7%94%BB"></a><a
            name="%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E5%8A%A8%E7%94%BB"></a>     <h4>弹出框的动画</h4>
        <p>弹出框通过定义openAnimation控制弹出框出现动画的持续时间，速度等参数。</p>
        <pre class="ts">@CustomDialog
struct CustomDialogExample {
  controller?: CustomDialogController;

  build() {
    Column() {
      Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
    }
  }
}

@Entry
@Component
struct CustomDialogUser {
  @State textValue: string = '';
  @State inputValue: string = 'click me';
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample(),
    openAnimation: {
      duration: 1200,
      curve: Curve.Friction,
      delay: 500,
      playMode: PlayMode.Alternate,
      onFinish: () =&gt; {
        console.info('play end')
      }
    },
    autoCancel: true,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -20 },
    gridCount: 4,
    customStyle: false,
    backgroundColor: 0xd9ffffff,
    cornerRadius: 10,
  });

  // 在自定义组件即将析构销毁时将dialogController置空
  aboutToDisappear() {
    this.dialogController = null; // 将dialogController置空
  }

  build() {
    Column() {
      Button(this.inputValue)
        .onClick(() =&gt; {
          if (this.dialogController != null) {
            this.dialogController.open();
          }
        }).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
  }
}</pre>
        <p><span><img originheight="779" originwidth="352"
                      src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163042.93328399707234309142922194420384:50001231000000:2800:3C932981DFF34B304BCA4178DE0592046452B7A87031BD37FB2EB76FCD4FC92B.gif"></span>
        </p></div>
    <div class="section" id="弹出框的样式"><a
            name="ZH-CN_TOPIC_0000002278863244__%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E6%A0%B7%E5%BC%8F"></a><a
            name="%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E6%A0%B7%E5%BC%8F"></a>     <h4>弹出框的样式</h4>
        <p>通过定义弹出框的宽度、高度、背景色、阴影等参数，控制其样式。</p>
        <pre class="ts">@CustomDialog
struct CustomDialogExample {
  controller?: CustomDialogController;

  build() {
    Column() {
      Text('我是内容').fontSize(16).margin({ bottom: 10 })
    }
  }
}

@Entry
@Component
struct CustomDialogUser {
  @State textValue: string = '';
  @State inputValue: string = 'click me';
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample(),
    autoCancel: true,
    alignment: DialogAlignment.Center,
    offset: { dx: 0, dy: -20 },
    gridCount: 4,
    customStyle: false,
    backgroundColor: 0xd9ffffff,
    cornerRadius: 20,
    width: '80%',
    height: '100px',
    borderWidth: 1,
    borderStyle: BorderStyle.Dashed,//使用borderStyle属性，需要和borderWidth属性一起使用
    borderColor: Color.Blue,//使用borderColor属性，需要和borderWidth属性一起使用
    shadow: ({ radius: 20, color: Color.Grey, offsetX: 50, offsetY: 0}),
  });

  // 在自定义组件即将析构销毁时将dialogController置空
  aboutToDisappear() {
    this.dialogController = null; // 将dialogController置空
  }

  build() {
    Column() {
      Button(this.inputValue)
        .onClick(() =&gt; {
          if (this.dialogController != null) {
            this.dialogController.open();
          }
        }).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
  }
}</pre>
        <p><span><img originheight="455" originwidth="347"
                      src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163042.49910728120394681526226296284831:50001231000000:2800:C95D67F091D58361CEBC2556205F0957A33C2DAE0A504D5BFF6B73E7F8A21308.gif"></span>
        </p></div>
    <div class="section" id="嵌套自定义弹出框"><a
            name="ZH-CN_TOPIC_0000002278863244__%E5%B5%8C%E5%A5%97%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BC%B9%E5%87%BA%E6%A1%86"></a><a
            name="%E5%B5%8C%E5%A5%97%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BC%B9%E5%87%BA%E6%A1%86"></a>     <h4>
        嵌套自定义弹出框</h4>
        <p>
            通过第一个弹出框打开第二个弹出框时，最好将第二个弹出框定义在第一个弹出框的父组件处，通过父组件传给第一个弹出框的回调来打开第二个弹出框。</p>
        <pre class="ts">@CustomDialog
struct CustomDialogExampleTwo {
  controllerTwo?: CustomDialogController;
  @State message: string = "I'm the second dialog box.";
  @State showIf: boolean = false;

  build() {
    Column() {
      if (this.showIf) {
        Text("Text")
          .fontSize(30)
          .height(100)
      }
      Text(this.message)
        .fontSize(30)
        .height(100)
      Button("Create Text")
        .onClick(() =&gt; {
          this.showIf = true;
        })
      Button('Close Second Dialog Box')
        .onClick(() =&gt; {
          if (this.controllerTwo != undefined) {
            this.controllerTwo.close();
          }
        })
        .margin(20)
    }
  }
}

@CustomDialog
struct CustomDialogExample {
  openSecondBox?: () =&gt; void
  controller?: CustomDialogController

  build() {
    Column() {
      Button('Open Second Dialog Box and close this box')
        .onClick(() =&gt; {
          this.controller!.close();
          this.openSecondBox!();
        })
        .margin(20)
    }.borderRadius(10)
  }
}

@Entry
@Component
struct CustomDialogUser {
  @State inputValue: string = 'Click Me';
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      openSecondBox: () =&gt; {
        if (this.dialogControllerTwo != null) {
          this.dialogControllerTwo.open()
        }
      }
    }),
    cancel: this.exitApp,
    autoCancel: true,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -20 },
    gridCount: 4,
    customStyle: false
  });
  dialogControllerTwo: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExampleTwo(),
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -25 }
  });

  aboutToDisappear() {
    this.dialogController = null;
    this.dialogControllerTwo = null;
  }

  onCancel() {
    console.info('Callback when the first button is clicked');
  }

  onAccept() {
    console.info('Callback when the second button is clicked');
  }

  exitApp() {
    console.info('Click the callback in the blank area');
  }

  build() {
    Column() {
      Button(this.inputValue)
        .onClick(() =&gt; {
          if (this.dialogController != null) {
            this.dialogController.open();
          }
        }).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
  }
}</pre>
        <p><span><img originheight="687" originwidth="308"
                      src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163042.56857863563745356826497936948880:50001231000000:2800:66D6FE49E5596D5EF002F5DEB839B384837BFC8511E5A4258E67FBE63499B848.gif"></span>
        </p>
        <p>
            由于自定义弹出框在状态管理侧有父子关系，如果将第二个弹出框定义在第一个弹出框内，那么当父组件（第一个弹出框）被销毁（关闭）时，子组件（第二个弹出框）内无法再继续创建新的组件。</p>
    </div>
    <div class="section" id="实现弹出框的物理返回拦截"><a
            name="ZH-CN_TOPIC_0000002278863244__%E5%AE%9E%E7%8E%B0%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E7%89%A9%E7%90%86%E8%BF%94%E5%9B%9E%E6%8B%A6%E6%88%AA"></a><a
            name="%E5%AE%9E%E7%8E%B0%E5%BC%B9%E5%87%BA%E6%A1%86%E7%9A%84%E7%89%A9%E7%90%86%E8%BF%94%E5%9B%9E%E6%8B%A6%E6%88%AA"></a>
        <h4>实现弹出框的物理返回拦截</h4>
        <p>执行点击遮障层关闭、侧滑（左滑或右滑）、三键Back、键盘ESC关闭等交互操作时，如果注册了<a
                href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box#customdialogcontrolleroptions对象说明"
                target="_blank">onWillDismiss</a>回调函数，弹出框不会立即关闭。在回调函数中，通过<a
                href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box#dismissdialogaction12"
                target="_blank">reason</a>获取阻拦关闭弹出框的操作类型，根据原因决定是否关闭弹出框。</p>
        <pre class="ts">@CustomDialog
struct CustomDialogExample {
  cancel: () =&gt; void = () =&gt; {
  }
  confirm: () =&gt; void = () =&gt; {
  }
  controller?: CustomDialogController;

  build() {
    Column() {
      Text('Are you sure?')
        .fontSize(20)
        .margin({
          top: 10,
          bottom: 10
        })
      Row() {
        Button('cancel')
          .onClick(() =&gt; {
            if (this.controller != undefined) {
              this.controller.close();
            }
          })
          .backgroundColor(0xffffff)
          .fontColor(Color.Black)
        Button('confirm')
          .onClick(() =&gt; {
            if (this.controller != undefined) {
              this.controller.close();
            }
          })
          .backgroundColor(0xffffff)
          .fontColor(Color.Red)
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
      .margin({ bottom: 10 })
    }
  }
}

@Entry
@Component
struct InterceptCustomDialog {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: () =&gt; {
        this.onCancel();
      },
      confirm: () =&gt; {
        this.onAccept();
      }
    }),
    onWillDismiss: (dismissDialogAction: DismissDialogAction) =&gt; {
      console.info('dialog onWillDismiss reason: ' + dismissDialogAction.reason);
      // 1、PRESS_BACK    点击三键back、侧滑（左滑/右滑）、键盘ESC。
      // 2、TOUCH_OUTSIDE    点击遮障层时
      // 3、CLOSE_BUTTON    点击关闭按钮
      if (dismissDialogAction.reason === DismissReason.PRESS_BACK) {
        // 处理业务逻辑后通过dismiss主动关闭对话框
        // dismissDialogAction.dismiss();
      }
      if (dismissDialogAction.reason === DismissReason.TOUCH_OUTSIDE) {
        // dismissDialogAction.dismiss();
      }
    },
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -20 }
  })

  onCancel() {
    console.info('Callback when the first button is clicked');
  }

  onAccept() {
    console.info('Callback when the second button is clicked');
  }

  build() {
    Column() {
      Button('click me')
        .onClick(() =&gt; {
          this.dialogController.open();
        })
    }
    .width('100%')
  }
}</pre>
        <p><span><img originheight="759" originwidth="351"
                      src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163042.97453427478415407037496622064320:50001231000000:2800:55853CB66F9781537165F9305A787381C0766D51297A6E1E8C42ED51865600D3.gif"></span>
        </p></div>
    <div class="section" id="设置弹出框避让软键盘的距离"><a
            name="ZH-CN_TOPIC_0000002278863244__%E8%AE%BE%E7%BD%AE%E5%BC%B9%E5%87%BA%E6%A1%86%E9%81%BF%E8%AE%A9%E8%BD%AF%E9%94%AE%E7%9B%98%E7%9A%84%E8%B7%9D%E7%A6%BB"></a><a
            name="%E8%AE%BE%E7%BD%AE%E5%BC%B9%E5%87%BA%E6%A1%86%E9%81%BF%E8%AE%A9%E8%BD%AF%E9%94%AE%E7%9B%98%E7%9A%84%E8%B7%9D%E7%A6%BB"></a>
        <h4>设置弹出框避让软键盘的距离</h4>
        <p>为显示弹出框的独立性，弹出框弹出时会与周边进行避让，包括状态栏、导航条以及键盘等留有间距。故当软键盘弹出时，默认情况下，弹出框会自动避开软键盘，并与之保持16vp的距离。开发者可以利用<a
                href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box#customdialogcontrolleroptions对象说明"
                target="_blank">CustomDialogControllerOptions</a>中的keyboardAvoidMode和keyboardAvoidDistance这两个配置项，来设置弹出框在软键盘弹出时的行为，包括是否需要避开软键盘以及与软键盘之间的距离。
        </p>
        <p>设置软键盘间距时，需要将keyboardAvoidMode值设为KeyboardAvoidMode.DEFAULT。</p>
        <pre class="ts">// xxx.ets
import { LengthMetrics } from '@kit.ArkUI'

@CustomDialog
struct CustomDialogExample {
  controller?: CustomDialogController;
  build() {
    Column() {
      Column() {
        Text('keyboardAvoidDistance: 0vp')
          .fontSize(20)
          .margin({ bottom: 36 })
        TextInput({ placeholder: '' })
      }.backgroundColor('#FFF0F0F0')
    }
  }
}

@Entry
@Component
struct Index {
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
    }),
    autoCancel: true,
    gridCount: 4,
    showInSubWindow: true,
    isModal: true,
    customStyle: false,
    cornerRadius: 30,
    alignment:DialogAlignment.Bottom,
    keyboardAvoidMode: KeyboardAvoidMode.DEFAULT, // 软键盘弹出时，弹出框自动避让
    keyboardAvoidDistance: LengthMetrics.vp(0) // 软键盘弹出时与弹出框的距离为0vp
  })

  build() {
    Row() {
      Row({ space: 20 }) {
        Text('打开弹窗')
          .fontSize(30)
          .onClick(() =&gt; {
            if (this.dialogController != null) {
              this.dialogController.open();
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}</pre>
        <p><span><img originheight="662" originwidth="400"
                      src="https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20250709163042.41458312522175059873711888914773:50001231000000:2800:F18863AFD54D968372A3ACBC9FB5E02AD9F1A2E180F4E73FB06DBA782232C54A.gif"></span>
        </p></div>
</div>
<div></div>
</body>
</html>